热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

循环结构与零钱问题:多题型综合解析与应用

篇首语:本文由编程笔记#小编为大家整理,主要介绍了各题型归纳总结相关的知识,希望对你有一定的参考价值。 文章目录 二分两种代码模板代码1代码2 思考有重复元素的情况山峰数组 动态规划从题目

篇首语:本文由编程笔记#小编为大家整理,主要介绍了各题型归纳总结相关的知识,希望对你有一定的参考价值。



文章目录


  • 二分
    • 两种代码模板
      • 代码1
      • 代码2

    • 思考
      • 有重复元素的情况
      • 山峰数组


  • 动态规划
    • 从题目中辨识是否用DP
      • 重复子问题
        • 剑指 Offer 46. 把数字翻译成字符串
        • 91. 解码方法

      • 最优子结构
        • 322. 零钱兑换
        • 279. 完全平方数
        • 343. 整数拆分
        • 377. 组合总和 Ⅳ

      • ==无后效性【多阶段、有约束 的决策最优化问题】==
        • 不同路径
        • 打家劫舍



  • 贪心


二分

两种代码模板


代码1


  • 代码1:在循环中查找元素
    适合知道num[mid]等于什么,才能得到结果的情况

public class Solution

// 「力扣」第 704 题:二分查找
public int search(int[] nums, int target)
int len = nums.length;
int left = 0;
int right = len - 1;
// 目标元素可能存在在区间 [left, right]
//区间还剩一个元素时,继续循环
while (left <&#61; right)
// 推荐的写法是 int mid &#61; left &#43; (right - left) / 2;
int mid &#61; (left &#43; right) / 2;
if (nums[mid] &#61;&#61; target)
return mid;
else if (nums[mid] < target)
// 目标元素可能存在在区间 [mid &#43; 1, right]
left &#61; mid &#43; 1;
else
// 目标元素可能存在在区间 [left, mid - 1]
right &#61; mid - 1;


return -1;



代码2


  • 代码2&#xff08;1&#xff09;&#xff1a;在循环体中排除目标元素一定不存在的区间
    适合 不知道num[mid]等于什么 才能得到结果&#xff0c;但知道什么情况下可以缩小区间&#xff0c;的情况。
    使用 if (nums[mid]

public class Solution

// 「力扣」第 704 题&#xff1a;二分查找
public int search(int[] nums, int target)
int len &#61; nums.length;
int left &#61; 0;
int right &#61; len - 1;
// 目标元素可能存在在区间 [left, right]
//区间还剩一个元素时&#xff0c;退出循环
while (left < right)
int mid &#61; left &#43; (right - left) / 2;
//这里注意使用nums[mid]
//若使用nums[mid] > target,则mid需要上取整&#xff1b;
if (nums[mid] < target)
// 下一轮搜索区间是 [mid &#43; 1, right]
left &#61; mid &#43; 1;
else
// 下一轮搜索区间是 [left, mid]
right &#61; mid;


if (nums[left] &#61;&#61; target)
return left;

return -1;



  • 代码2&#xff08;2&#xff09;&#xff1a;在循环体中排除目标元素一定不存在的区间

使用if (nums[mid] > target) 判断&#xff1b;会出现left &#61; mid&#xff1b;mid需要上取整:int mid &#61; left &#43; (right - left &#43; 1) / 2;防止死循环

即&#xff0c;出现left &#61; mid情况&#xff0c;mid需向上取整int mid &#61; left &#43; (right - left &#43; 1) / 2;防止死循环。

public class Solution

// 「力扣」第 704 题&#xff1a;二分查找
public int search(int[] nums, int target)
int len &#61; nums.length;
int left &#61; 0;
int right &#61; len - 1;
while (left < right)
int mid &#61; left &#43; (right - left &#43; 1) / 2;
if (nums[mid] > target)
// 下一轮搜索区间是 [left, mid - 1]
right &#61; mid - 1;
else
// 下一轮搜索区间是 [mid, right]
left &#61; mid;


if (nums[left] &#61;&#61; target)
return left;

return -1;



思考

二分的思想是&#xff0c;通过num[mid]与一个target对比&#xff0c;来缩小区间&#xff0c;


  • 当给定target时&#xff0c;自然与target比较&#xff1b;
  • 当未给定target时&#xff0c;找那些和mid比较 能产生缩小区间效果的元素&#xff0c;如&#xff1a;左右边界常作为target&#xff0c;

有重复元素的情况

针对有重复的情况&#xff0c;是将下面两种**无重复情况**下的划分&#xff1a;
nums[l] <&#61; nums[mid]
nums[l] > nums[mid])
改为下面三种划分&#xff0c;将等于的情况单独提取出来&#xff0c;【适合重复情况】
nums[l] < nums[mid]
nums[l] &#61;&#61; nums[mid] //若nums[l]不是目标值&#xff0c;因为相等&#xff0c;所以可以缩小一个范围&#xff0c;即l&#43;&#43;;
nums[l] > nums[mid])

在有序数组中进行查找一个数&#xff08;二分下标&#xff09;

在整数范围内查找一个整数&#xff08;二分答案&#xff09;


山峰数组

arr[mid] 与 arr[mid &#43; 1]比较


动态规划

找题目中的约束条件&#xff0c;然后根据约束条件定义状态



  • 动态规划的用途&#xff1a;求解多阶段决策问题
    动态规划解决的是这样一类问题&#xff1a;多阶段决策问题。这里的「阶段」就是生活语言&#xff1a;解决一个问题分很多步骤&#xff0c;每一个步骤又有很多种选择&#xff0c;这一点和「回溯算法」是一样的
    通常可以把多阶段决策问题画成一张树形图

  • 动态规划与回溯算法的区别
    「动态规划」与「回溯算法」在问题问法上的区别是&#xff1a;「动态规划」问题通常只问结果&#xff0c;即只问最优值是多少&#xff0c;或者问解决方案的个数&#xff0c;而不问具体解&#xff08;具体的解决方案&#xff09;是什么&#xff1b;
    「回溯算法」问题通常让我们给出一个问题的所有解决方案&#xff0c;要求我们返回的是一个嵌套列表



能够使用动态规划解决的问题&#xff0c;一定可以使用回溯算法解决。但是我们要清楚一个事实&#xff1a;回溯算法的时间复杂度很高。在只问最优值是多少的场景下&#xff0c;没有必要记录每个阶段的每一个步骤。动态规划方法很多时候的意义在于评估算法的上限。



从题目中辨识是否用DP


重复子问题


剑指 Offer 46. 把数字翻译成字符串

求&#xff1a;计算一个数字有多少种不同的翻译方法。
只是求有多少种&#xff0c;而不是求出每种的解决方案&#xff0c;即DP。【若求所有解决方案&#xff0c;则用回溯】


91. 解码方法

求&#xff1a;请计算并返回 解码 方法的 总数
只是求有多少种&#xff0c;而不是求出每种的解决方案&#xff0c;即DP。【若求所有解决方案&#xff0c;则用回溯】


最优子结构



它们的问法都一样&#xff1a;求解一个问题的最优值是多少&#xff0c;但没有问最优值是怎么来的。以后遇到这样的问题&#xff0c;需要有一定敏感&#xff0c;可能这个问题考察的是动态规划&#xff08;还有可能考察广度优先遍历、贪心算法&#xff09;。
分析最优子结构的重要方法依然是&#xff1a;通过研究具体的例子&#xff0c;画图分析。



322. 零钱兑换


279. 完全平方数


343. 整数拆分


377. 组合总和 Ⅳ



对于 nums &#61; [1,2,3], target &#61; 4
dp[4] &#61; dp[4 - 1] &#43; dp[4 - 2] &#43; dp[4 - 3]
即&#xff0c;
dp[target ] &#61; dp[target - nums[0] ] &#43; dp[target - nums[1] ] &#43; dp[target - nums[2] ] &#43; …【target - nums[2] >&#61;0)】


class Solution
public int combinationSum4(int[] nums, int target)
int[] dp &#61; new int[target &#43; 1];
//dp[0]没实际意思&#xff0c;由dp[1] &#61; 1 &#61; dp[0]推出&#xff1b;
dp[0] &#61; 1;
for(int j &#61; 1 ; j <&#61; target ; j&#43;&#43;)
for(int i &#61; 0 ; i < nums.length ; i&#43;&#43;)
if(j >&#61; nums[i]) dp[j] &#61; dp[j] &#43; dp[j - nums[i]];


return dp[target];



无后效性【多阶段、有约束 的决策最优化问题】


不同路径


  • 只需求出路径个数&#xff0c;不需求出具体方案&#xff1b;

打家劫舍


  • 题目只问最优值&#xff0c;并没有问最优解&#xff0c;因此可以考虑使用「动态规划」
  • 约束条件&#xff1a;在不触动警报装置的情况下&#xff0c;
    即分一个房子偷或不偷两种情况&#xff1b;

贪心



推荐阅读
  • 丽江客栈选择问题
    本文介绍了一道经典的算法题,题目涉及在丽江河边的n家特色客栈中选择住宿方案。两位游客希望住在色调相同的两家客栈,并在晚上选择一家最低消费不超过p元的咖啡店小聚。我们将详细探讨如何计算满足条件的住宿方案总数。 ... [详细]
  • 本教程详细介绍了如何使用 TensorFlow 2.0 构建和训练多层感知机(MLP)网络,涵盖回归和分类任务。通过具体示例和代码实现,帮助初学者快速掌握 TensorFlow 的核心概念和操作。 ... [详细]
  • 探讨 HDU 1536 题目,即 S-Nim 游戏的博弈策略。通过 SG 函数分析游戏胜负的关键,并介绍如何编程实现解决方案。 ... [详细]
  • 本文探讨了在Django项目中,如何在对象详情页面添加前后导航链接,以提升用户体验。文章详细描述了遇到的问题及解决方案。 ... [详细]
  • Google排名优化-面向Google(Search Engine Friendly)的URL设计 ... [详细]
  • ML学习笔记20210824分类算法模型选择与调优
    3.模型选择和调优3.1交叉验证定义目的为了让模型得精度更加可信3.2超参数搜索GridSearch对K值进行选择。k[1,2,3,4,5,6]循环遍历搜索。API参数1& ... [详细]
  • 本文详细探讨了JavaScript中的作用域链和闭包机制,解释了它们的工作原理及其在实际编程中的应用。通过具体的代码示例,帮助读者更好地理解和掌握这些概念。 ... [详细]
  • 本题探讨了在大数据结构背景下,如何通过整体二分和CDQ分治等高级算法优化处理复杂的时间序列问题。题目设定包括节点数量、查询次数和权重限制,并详细分析了解决方案中的关键步骤。 ... [详细]
  • JSOI2010 蔬菜庆典:树结构中的无限大权值问题
    本文探讨了 JSOI2010 的蔬菜庆典问题,主要关注如何处理非根非叶子节点的无限大权值情况。通过分析根节点及其子树的特性,提出了有效的解决方案,并详细解释了算法的实现过程。 ... [详细]
  • 2018-2019学年第六周《Java数据结构与算法》学习总结
    本文总结了2018-2019学年第六周在《Java数据结构与算法》课程中的学习内容,重点介绍了非线性数据结构——树的相关知识及其应用。 ... [详细]
  • Nginx 反向代理与负载均衡实验
    本实验旨在通过配置 Nginx 实现反向代理和负载均衡,确保从北京本地代理服务器访问上海的 Web 服务器时,能够依次显示红、黄、绿三种颜色页面以验证负载均衡效果。 ... [详细]
  • 实用正则表达式有哪些
    小编给大家分享一下实用正则表达式有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • 深入解析动态代理模式:23种设计模式之三
    在设计模式中,动态代理模式是应用最为广泛的一种代理模式。它允许我们在运行时动态创建代理对象,并在调用方法时进行增强处理。本文将详细介绍动态代理的实现机制及其应用场景。 ... [详细]
  • 本文探讨了SSDP(简单服务发现协议)和WSD(Web服务发现)协议,特别是SSDP如何通过固定多播地址239.255.255.250:1900实现局域网内的服务自发现功能。文中还详细介绍了SSDP协议的关键操作类型及其应用场景。 ... [详细]
author-avatar
艾米27
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有